package com.xiu.travel.util;

import com.baomidou.mybatisplus.annotation.IEnum;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 获取MybatisPlus 的Wrapper
 *
 * @author : 20220312
 * @since : 2023/3/27 16:58
 */

@Slf4j
public class ControllerPageParmaAppendUtil {
    public static <T> QueryWrapper<T> getQueryDataWrapper(Page<T> page, List<DataBO> data) throws IllegalAccessException {
        Object param = new Object();
        QueryWrapper<T> queryWrapper = Wrappers.query();
        System.out.println(page);
        if (page != null) {
            for (OrderItem order : page.orders()) {
                order.setColumn(StringUtil.camelToUnderline(order.getColumn()));
            }
            if (!CollectionUtils.isEmpty(page.getRecords())) {
                param = page.getRecords().get(0);
            }
            log.info("param:{}", param);
            Field[] fields = param.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                if (Objects.nonNull(field.get(param))) {
                    //有的字段是用private修饰的 将他设置为可读
                    if (!"serialVersionUID".equals(field.getName())) {
                        log.info(" isDataType(field):{}", isDataType(field));
                        if (!"".equals(field.get(param))) {
                            String name = StringUtil.camelToUnderline(field.getName());
                            if ("date_list".equals(name)) {
                                continue;
                            }
                            if (isNumberType(field)) {
                                queryWrapper.eq(name, field.get(param));
                            } else if (isDataType(field)) {
                                // 日期格式化字符串
                                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                queryWrapper.between(name, field.get(param), sdf.format(System.currentTimeMillis()));
                            } else if (isStringType(field)) {
                                switch (name) {
                                    case "status", "sn" -> queryWrapper.eq(name, field.get(param));
                                    default -> queryWrapper.like(name, field.get(param));
                                }
                            } else if (isEnumType(field)) {
                                queryWrapper.eq(name, ((IEnum<?>) field.get(param)).getValue());
                            }
                        }
                    }
                }
            }
        }

        if (data != null) {
            for (DataBO dataBO : data) {
                if (ObjectUtils.isEmpty(dataBO.start) || ObjectUtils.isEmpty(dataBO.end)) continue;
                queryWrapper.between(dataBO.column, dataBO.start, dataBO.end);
            }
        }
        return queryWrapper;
    }

    public static <T> QueryWrapper<T> getQueryWrapper(Page<T> page) throws IllegalAccessException {
        for (OrderItem order : page.orders()) {
            order.setColumn(StringUtil.camelToUnderline(order.getColumn()));
        }
        Object param = new Object();
        if (!CollectionUtils.isEmpty(page.getRecords())) {
            param = page.getRecords().get(0);
        }
        log.info("param:{}", param);
        QueryWrapper<T> queryWrapper = Wrappers.query();
        Field[] fields = param.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            if (Objects.nonNull(field.get(param))) {
                //有的字段是用private修饰的 将他设置为可读
                if (!"serialVersionUID".equals(field.getName())) {
                    log.info(" isDataType(field):{}", isDataType(field));
                    if (!"".equals(field.get(param))) {
                        String name = StringUtil.camelToUnderline(field.getName());
                        if ("date_list".equals(name)) {
                            continue;
                        }
                        if (isNumberType(field)) {
                            queryWrapper.eq(name, field.get(param));
                        } else if (isDataType(field)) {
                            // 日期格式化字符串
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            queryWrapper.between(name, field.get(param), sdf.format(System.currentTimeMillis()));
                        } else if (isStringType(field)) {
                            switch (name) {
                                case "status", "sn" -> queryWrapper.eq(name, field.get(param));
                                default -> queryWrapper.like(name, field.get(param));
                            }
                        } else if (isEnumType(field)) {
                            queryWrapper.eq(name, ((IEnum<?>) field.get(param)).getValue());
                        }
                    }
                }
            }
        }
        return queryWrapper;
    }

    private static boolean isNumberType(Field field) {
        return Arrays.asList(new String[]{"class java.lang.Long", "class java.lang.Integer"}).contains(field.getType().toString());
    }

    private static boolean isDataType(Field field) {
        return Arrays.asList(new String[]{"class java.util.Date", "class java.time.LocalDate"}).contains(field.getType().toString());
    }

    private static boolean isEnumType(Field field) {
        return field.getType().isEnum() && IEnum.class.isAssignableFrom(field.getType());
    }

    private static boolean isStringType(Field field) {
        return Arrays.asList(new String[]{"class java.lang.String"}).contains(field.getType().toString());
    }

    public record DataBO(String column, Date start, Date end) {

    }

}
